package com.gcsoftware.gateway.filters.http.response;

import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gcsoftware.gateway.GWImpl.basics.gatewayMasker;
import com.gcsoftware.gateway.utils.HttpUtil;
import com.gcsoftware.gateway.utils.enTextContentType;
import com.gcsoftware.gateway.utils.exception.UnsupportedCharsetException;
import com.gcsoftware.gateway.utils.httpObject.BrowserMobHttpUtil;

import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;

/**
 * Created by yinpeng on 18/1/23.
 */
public class RespContentRewrite
{
    private static final Logger log = LoggerFactory.getLogger(RespContentRewrite.class);

    private Map<String ,Object> argsMap;

    public RespContentRewrite(Map<String, Object> argsMap) {
        this.argsMap = argsMap;
    }
    //private static String argName;

    //public static void setArgName(String argName) {
    //    respContentRewrite.argName = argName;
    //}

    public FullHttpResponse getContentAsString(HttpRequest originalRequest, FullHttpResponse resp)
    {
        try
        {
            ByteArrayOutputStream rawResponseContents = new ByteArrayOutputStream();
            byte[] content = BrowserMobHttpUtil.extractReadableBytes(resp.content());

            rawResponseContents.write(content);

            rawResponseContents = BrowserMobHttpUtil.decompressContents(resp, rawResponseContents);

            String contentType = HttpHeaders.getHeader(resp, HttpHeaders.Names.CONTENT_TYPE);
            String textafter;
            Charset charset=null;
            try
            {
                charset = BrowserMobHttpUtil.readCharsetInContentTypeHeader(contentType);
            }
            catch (UnsupportedCharsetException e)
            {
                log.warn(
                        "Found unsupported character set in Content-Type header '{}' in HTTP response from {}. Content will not be captured in HAR.",
                        contentType, originalRequest.getUri(), e);

            }

            if (charset == null) {
                // no charset specified, so use the default -- but log a message since this might not encode the data correctly
                charset = BrowserMobHttpUtil.DEFAULT_HTTP_CHARSET;
            }
            //FullHttpResponse resp2 = resp;

            log.debug("contentType :{}", contentType);
            if (BrowserMobHttpUtil.hasTextualContent(contentType)) {
                String text = BrowserMobHttpUtil.getContentAsString(rawResponseContents.toByteArray(), charset);

                log.debug("*****text before:{}" ,text);

                //textafter = MaskerReplace4JSON.MaskerReplace(text);
                gatewayMasker masker = new gatewayMasker(argsMap);
                enTextContentType conTextType = BrowserMobHttpUtil.getContentTypeAsEnum(contentType);
                textafter = masker.execute(text, conTextType , charset.displayName());


                log.debug("*****text after:{}",textafter);

                resp.content().resetWriterIndex();

                // resize the buffer if needed, since the new message may be longer than the old one
                resp.content().ensureWritable(textafter.getBytes(charset).length, true);
                resp.content().writeBytes(textafter.getBytes(charset));
                resp.headers().set(HttpHeaders.Names.CONTENT_LENGTH, resp.content().readableBytes());

                log.debug("pliantext:[{}]"+System.getProperty("line.separator")+"maskertext:[{}]", text, textafter);

                //@todo write log for analysis involving as
                // [SourceIP][DestinationIP][InterfaceName][APP_ID][Token_ID(此字段预留，暂时为空)][Role_ID][Role_Name][sensitiveItem_1,sensitiveItem_2,sensitiveItem_3,sensitiveItem_4,sensitiveItem_5,.....sensitiveItem_N][sensitiveItem_Name_1,sensitiveItem_Name_2,sensitiveItem_Name_3,......sensitiveItem_Name_N]

                //@todo need to be test, below as just sample code for use HttpUtil and HttpHeaders
                String targetHost = HttpUtil.getReqHeadByName(originalRequest, HttpHeaders.Names.HOST);
                String SrcAddr = HttpUtil.getReqHeadByName(originalRequest, HttpHeaders.Names.FROM);

            }

            return resp;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            log.warn("getContentAsString throw exception, will return original response!", e);
            return resp;
        }
    }

}
